import json
import traceback

import aioboto3

from apps.global_config import configs
from apps.models.ResponseModel import error, success


class S3Util:
    boto_session = None
    boto_session_scm = None
    boto_session_ro = None
    region_name = None
    secret_name = None

    @classmethod
    async def initialize_class_variable(cls):
        if configs.SELECT_NAME == "s3":
            if cls.boto_session_scm is None:
                cls.boto_session_scm = aioboto3.Session(aws_access_key_id=configs.S3_ACCESS_KEY_ID,
                                                        aws_secret_access_key=configs.S3_SECRET_ACCESS_KEY)
                cls.secret_name = "skybug-cqvip/product/guji.cqvip_s3_ro"
                # secret_name = "skybug-cqvip/product/guji.cqvip_s3_rw"
                cls.region_name = "cn-northwest-1"
                if cls.boto_session_ro is None:
                    await cls.get_secret_value()

        else:
            if cls.boto_session is None:
                cls.boto_session = aioboto3.Session(aws_access_key_id=configs.ACCESS_KEY_ID,
                                                    aws_secret_access_key=configs.SECRET_ACCESS_KEY)

    @classmethod
    async def get_secret_value(cls):
        async with cls.boto_session_scm.client("secretsmanager", region_name=cls.region_name) as client:
            get_secret_value_response = await client.get_secret_value(SecretId=cls.secret_name)
            aws_access_key_id = json.loads(get_secret_value_response['SecretString'])['AK']
            aws_secret_access_key = json.loads(get_secret_value_response['SecretString'])['SK']
            # print(aws_access_key_id, aws_secret_access_key)
            cls.boto_session_ro = aioboto3.Session(aws_access_key_id=aws_access_key_id,
                                                   aws_secret_access_key=aws_secret_access_key)

    @classmethod
    async def read_s3_data(cls, key):
        await cls.initialize_class_variable()
        if configs.SELECT_NAME == "s3":
            key = configs.S3_PREFIX + "/" + key
            return await cls._read_aws_data(key)
        else:
            return await cls._read_minio_data(key)

    @classmethod
    async def _read_aws_data(cls, key, is_return=False):
        """
        is_return = True 只有 在当前函数中调用时赋予True

        """
        try:
            async with cls.boto_session_ro.client('s3', region_name=cls.region_name) as s3:
                s3_obs = await s3.get_object(Bucket=configs.S3_BUCKET,
                                             Key=key)
                result = (await s3_obs["Body"].read()).decode("utf-8")
                return success(result, "success")
        except Exception as e:
            traceback.print_exc()
            await cls.get_secret_value()
            if is_return:
                return error(501, "".join(["aws s3读取错误: ", key, " err:", repr(e)]))
            else:
                return await cls._read_aws_data(key, is_return=True)

    @classmethod
    async def _read_minio_data(cls, key):
        try:
            async with cls.boto_session.client('s3', endpoint_url=configs.ENDPOINT_URL) as s3:
                s3_ob = await s3.get_object(Bucket=configs.BUCKET, Key=key)
                result = (await s3_ob["Body"].read()).decode("utf-8")
                return success(result, "success")
        except Exception as e:
            traceback.print_exc()
            return error(501, "".join(["minio读取错误: ", key, " err:", repr(e)]))
